package com.ds.esd.admin.plugins.service;

import com.alibaba.fastjson.JSONObject;
import com.ds.common.JDSException;
import com.ds.common.md5.MD5InputStream;
import com.ds.common.util.StringUtility;
import com.ds.config.ErrorListResultModel;
import com.ds.config.ErrorResultModel;
import com.ds.config.ListResultModel;
import com.ds.config.ResultModel;
import com.ds.context.JDSActionContext;
import com.ds.enums.db.MethodChinaName;
import com.ds.esd.admin.node.XUIFile;
import com.ds.esd.admin.node.XUIFileVersion;
import com.ds.esd.admin.node.XUIModule;
import com.ds.esd.admin.node.XUIParas;
import com.ds.esd.client.ESDClient;
import com.ds.esd.client.ESDFacrory;
import com.ds.esd.client.ProjectVersion;
import com.ds.esd.editor.enums.PackagePathType;
import com.ds.esd.editor.enums.PackageType;
import com.ds.esd.project.enums.ProjectDefAccess;
import com.ds.esd.tool.enums.EUFileType;
import com.ds.esd.tool.module.EUModule;
import com.ds.esd.tool.ui.module.ModuleComponent;
import com.ds.vfs.FileInfo;
import com.ds.vfs.FileVersion;
import com.ds.vfs.Folder;
import com.ds.vfs.VFSConstants;
import com.ds.vfs.ct.CtVfsFactory;
import com.ds.vfs.ct.CtVfsService;
import com.ds.web.util.PageUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Controller
@RequestMapping(value = {"/RAD/{projectName}/"})
@MethodChinaName(cname = "XUI编辑器")
public class VFSService {


    @MethodChinaName(cname = "添加文件夹")
    @RequestMapping(value = {"addFolder"}, method = {RequestMethod.POST})
    public @ResponseBody
    ResultModel<XUIFile> addFolder(String path, @PathVariable String projectName) {
        ResultModel<XUIFile> result = new ResultModel<XUIFile>();
        try {
            ProjectVersion version = getClient().getProjectVersionByName(projectName);
            Folder folder = version.createFolder(path);
            result.setData(new XUIFile(folder, version));
        } catch (JDSException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
            ((ErrorResultModel) result).setErrdes(e.getMessage());

        }
        return result;
    }

    @MethodChinaName(cname = "刷新工程")
    @RequestMapping(value = {"reLoadProject"}, method = {RequestMethod.POST})
    public @ResponseBody
    ResultModel<XUIFile> reLoadProject(@PathVariable String projectName) {
        ResultModel<XUIFile> result = new ResultModel<XUIFile>();
        try {
            getClient().reLoadProject(projectName);
        } catch (JDSException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
            ((ErrorResultModel) result).setErrdes(e.getMessage());

        }
        return result;
    }


    @MethodChinaName(cname = "添加普通文件")
    @RequestMapping(value = {"addTextFile"}, method = {RequestMethod.POST})
    public @ResponseBody
    ResultModel<XUIFile> addTextFile(String path, @PathVariable String projectName) {
        ResultModel<XUIFile> result = new ResultModel<XUIFile>();

        try {
            ProjectVersion version = getClient().getProjectVersionByName(projectName);
            FileInfo fileInfo = getClient().saveFile(new StringBuffer("{}"), path, projectName);
            result.setData(new XUIFile(fileInfo, version));
        } catch (JDSException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @MethodChinaName(cname = "添加页面")
    @RequestMapping(value = {"addClass"}, method = {RequestMethod.POST})
    public @ResponseBody
    ResultModel<XUIFile> addClass(String className, String projectName) {
        ResultModel<XUIFile> result = new ResultModel<XUIFile>();
        try {
            ProjectVersion version = getClient().getProjectVersionByName(projectName);
            EUModule module = getClient().getModule(className, version.getVersionName(), true);
            if (module == null) {
                EUModule euModule = version.createModule(className);
                getClient().saveModule(euModule);
                result.setData(new XUIFile(euModule));
            } else {
                throw new JDSException("页面已存在！");
            }
        } catch (JDSException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @MethodChinaName(cname = "添加文件")
    @RequestMapping(value = {"uploadFiles"}, method = {RequestMethod.POST})
    public @ResponseBody
    ResultModel<XUIFile> uploadFiles(String uploadpath, @PathVariable String projectName, @RequestParam("files") MultipartFile files, @RequestParam("file") MultipartFile file) {
        ResultModel<XUIFile> result = new ResultModel<XUIFile>();
        if (uploadpath == null) {
            uploadpath = "";
        }

        if (files == null) {
            files = file;
        }
        try {
            ProjectVersion version = getClient().getProjectVersionByName(projectName);
            if (uploadpath.equals(projectName)) {
                uploadpath = "";
            }
            Folder tfolder = getClient().getFolderByPath(uploadpath, version.getVersionName());
            if (tfolder == null) {
                tfolder = version.createFolder(uploadpath);
            }
            try {
                FileInfo fileInfo = getClient().uploadFile(new MD5InputStream(files.getInputStream()), tfolder.getPath() + files.getOriginalFilename(), projectName);
                result.setData(new XUIFile(fileInfo, version));
            } catch (IOException e) {
                throw new JDSException(e);
            }
        } catch (JDSException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

//
//    @MethodChinaName(cname = "添加文件")
//    @RequestMapping(value = {"addFile"}, method = {RequestMethod.POST})
//    public void addFile(String path, String fileName, @PathVariable String projectName, HttpServletRequest request, HttpServletResponse response, @RequestParam("file") MultipartFile file, String content) {
//        ResultModel<XUIFile> result = new ResultModel<XUIFile>();
//
//        if (path == null) {
//            path = "";
//        }
//        try {
//            ProjectVersion version = getClient().getProjectVersionByName(projectName);
//            if (path.equals(projectName)) {
//                path = "";
//            }
//
//            Folder tfolder = getClient().getFolderByPath(path, version.getVersionName());
//            if (tfolder == null) {
//                tfolder = version.createFolder(path);
//            }
//            FileInfo newfileInfo = getClient().getFileByPath(tfolder.getPath() + file.getOriginalFilename());
//            if (newfileInfo != null) {
//                result = new ErrorResultModel();
//                ((ErrorResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
//                ((ErrorResultModel) result).setErrdes("文件已存在！");
//            } else {
//                newfileInfo = tfolder.createFile(file.getOriginalFilename(), tfolder.getPersonId());
//                try {
//                    version.createFile(newfileInfo.getPath(), new MD5InputStream(file.getInputStream()));
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//            result.setData(new XUIFile(newfileInfo, version));
//
//        } catch (JDSException e) {
//            result = new ErrorResultModel();
//            ((ErrorResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
//            ((ErrorResultModel) result).setErrdes(e.getMessage());
//        }
//
//        try {
//            response.getWriter().write("<script type='text' id='json'>"
//                    + JSONObject.toJSON(result).toString()
//                    + "</script>" +
//                    "<script type='text/javascript'>parent.postMessage(document.getElementById('json').innerHTML,'" + request.getHeader("Origin") + "'); </script> ");
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }

    @MethodChinaName(cname = "导入文件")
    @RequestMapping(value = {"importFile"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<List<XUIFile>> importFile(String id, String tpath, @PathVariable String projectName) {
        ResultModel<List<XUIFile>> result = new ResultModel<List<XUIFile>>();
        List<XUIFile> xuiFiles = new ArrayList<XUIFile>();
        try {
            ProjectVersion version = getClient().getProjectVersionByName(projectName);
            String[] filePaths = StringUtility.split(id, ";");
            List<Object> objects = getClient().importFile(Arrays.asList(filePaths), tpath, projectName);
            for (Object obj : objects) {
                if (obj instanceof EUModule) {
                    xuiFiles.add(new XUIFile((EUModule) obj));
                } else if (obj instanceof FileInfo) {
                    xuiFiles.add(new XUIFile((FileInfo) obj, version));
                }
            }
            result.setData(xuiFiles);
        } catch (JDSException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
            ((ErrorResultModel) result).setErrdes(e.getMessage());

        }
        return result;
    }


    @MethodChinaName(cname = "拷贝文件夹")
    @RequestMapping(value = {"copy"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<XUIFile> copy(String spath, String tpath, String projectName) {
        ResultModel<XUIFile> result = new ResultModel<XUIFile>();
        try {
            ProjectVersion version = getClient().getProjectVersionByName(projectName);
            Object obj = getClient().copy(projectName, spath, tpath);
            if (obj instanceof EUModule) {
                result.setData(new XUIFile((EUModule) obj));
            } else if (obj instanceof FileInfo) {
                result.setData(new XUIFile((FileInfo) obj, version));
            } else if (obj instanceof Folder) {
                result.setData(new XUIFile((Folder) obj, version));
            }

        } catch (JDSException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
            ((ErrorResultModel) result).setErrdes(e.getMessage());

        }
        return result;
    }


    @MethodChinaName(cname = "获取文件内容")
    @RequestMapping(value = {"getFileContent"}, method = {RequestMethod.GET})
    public @ResponseBody
    ResultModel<XUIModule> getFileContent(String path, String className, @PathVariable String projectName) {
        ResultModel<XUIModule> result = new ResultModel<XUIModule>();
        XUIModule xuiModule = new XUIModule();
        String json = "{}";
        try {

            if (path != null && path.indexOf(VFSConstants.URLVERSION) > -1) {
                FileVersion version = CtVfsFactory.getCtVfsService().getFileVersionByPath(path);
                json = getClient().readFileAsString(path, projectName);
                ModuleComponent moduleComponent = JSONObject.parseObject(json, ModuleComponent.class);
                JDSActionContext.getActionContext().getContext().put("className", className + "V" + version.getIndex());
                moduleComponent.setClassName(className + "V" + version.getIndex());
                json = getClient().genJSON(moduleComponent, null).toString();

            } else if (className != null && !className.equals("")) {
                if (className.endsWith(".cls")) {
                    className = className.substring(0, className.length() - ".cls".length());
                    JDSActionContext.getActionContext().getContext().put("className", className);
                }
                EUModule module = getClient().getModule(path, projectName, false);
                if (module == null) {
                    EUModule euModule = getClient().createModule(className, projectName);
                    getClient().saveModule(euModule);
                }
                json = getClient().genJSON(module, null).toString();
            } else if (path.endsWith(".cls")) {
                EUModule module = getClient().getModule(path, projectName, false);
                if (module == null) {
                    EUModule euModule = getClient().createModule(className, projectName);
                    getClient().saveModule(euModule);
                }
                json = getClient().genJSON(module, null).toString();

            } else {
                json = getClient().readFileAsString(path, projectName);
            }
            xuiModule.setContent(json);
            result.setData(xuiModule);
        } catch (Exception e) {
            e.printStackTrace();
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
            ((ErrorResultModel) result).setErrdes(e.getMessage());

        }
        return result;
    }

    @MethodChinaName(cname = "删除文件")
    @RequestMapping(value = {"delFile"}, method = {RequestMethod.POST})
    public @ResponseBody
    ResultModel<XUIModule> delFile(String paths, @PathVariable String projectName) {
        ResultModel<XUIModule> result = new ResultModel<XUIModule>();
        XUIModule xuiModule = new XUIModule();
        List<XUIFile> modules = xuiModule.getFiles();
        try {
            ProjectVersion version = getClient().getProjectVersionByName(projectName);
            if (paths != null && paths.equals(projectName)) {
                getClient().delProject(getClient().getProjectByName(projectName).getId());
            } else {
                String[] filePath = StringUtility.split(paths, ";");
                version.delFile(Arrays.asList(filePath));
            }

        } catch (JDSException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @MethodChinaName(cname = "重新命名文件")
    @RequestMapping(value = {"reName"}, method = {RequestMethod.POST})
    public @ResponseBody
    ResultModel<XUIFile> reName(String path, String newName, @PathVariable String projectName) {
        ResultModel<XUIFile> result = new ResultModel<XUIFile>();

        try {
            ProjectVersion version = getClient().getProjectVersionByName(projectName);
            Object obj = getClient().reName(projectName, path, newName);
            if (obj instanceof EUModule) {
                result.setData(new XUIFile((EUModule) obj));
            } else if (obj instanceof FileInfo) {
                result.setData(new XUIFile((FileInfo) obj, version));
            } else if (obj instanceof Folder) {
                result.setData(new XUIFile((Folder) obj, version));
            }

        } catch (JDSException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }


    @MethodChinaName(cname = "打开文件夹")
    @RequestMapping(value = {"openFolder"}, method = {RequestMethod.POST})
    public @ResponseBody
    ListResultModel<List<XUIFile>> openFolder(String path, @PathVariable String projectName, Boolean hasFile) {
        ListResultModel<List<XUIFile>> result = new ListResultModel<List<XUIFile>>();
        String[] systemFiles = new String[]{"ProjectConfig.cfg", "xuiconf.js"};

        List<XUIFile> modules = new ArrayList<XUIFile>();
        Folder folder = null;
        ProjectVersion version = null;
        try {
            if (projectName != null) {
                if (path == null || projectName.equals(path)) {
                    path = "";
                }
                folder = getClient().getFolderByPath(path, projectName);
                version = getClient().getProjectVersionByName(projectName);
            } else {
                folder = this.getVfsClient().getFolderByPath(path);
            }

            List<Folder> folders = folder.getChildrenList();

            for (Folder cfolder : folders) {
                String folderPath = StringUtility.replace(cfolder.getPath(), version.getPath(), "/");
                PackagePathType packagePathType = PackagePathType.startPath(folderPath);
                if (packagePathType == null || packagePathType.getApiType().equals(PackageType.local) || version.getProject().getProjectType().equals(ProjectDefAccess.DSM)) {
                    boolean isSystem = false;
                    for (String name : systemFiles) {
                        if (cfolder.getName().equals(name)) {
                            isSystem = true;
                        }
                    }
                    if (!isSystem) {
                        modules.add(new XUIFile(cfolder, version));
                    }
                }
            }
            List<FileInfo> infos = folder.getFileList();
            for (FileInfo fileInfo : infos) {
                boolean isSystem = false;
                for (String name : systemFiles) {
                    if (fileInfo.getName().equals(name)) {
                        isSystem = true;
                    }
                }
                if (!isSystem) {
                    if (!fileInfo.getName().endsWith(".cls")) {
                        modules.add(new XUIFile(fileInfo, version));
                    } else {
                        EUModule module = version.getModule(fileInfo.getPath());
                        if (module != null) {
                            modules.add(new XUIFile(module));
                        }
                    }
                }


            }
            result.setData(modules);
        } catch (JDSException e) {
            result = new ErrorListResultModel<>();
            ((ErrorListResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
            ((ErrorListResultModel) result).setErrdes(e.getMessage());

        }

        return result;
    }


    @MethodChinaName(cname = "系统方法")
    @RequestMapping(value = {"request"}, method = {RequestMethod.GET
            , RequestMethod.POST})
    public @ResponseBody
    ResultModel<XUIModule> request(String key, String paras, @PathVariable String projectName) {
        ResultModel<XUIModule> result = new ResultModel<XUIModule>();
        XUIParas param = JSONObject.parseObject(paras, XUIParas.class);
        String path = param.getPath();
        XUIModule xuiModule = new XUIModule();
        if (param.getAction().equals("open") || param.getAction().equals("refresh")) {
            List<XUIFile> modules = xuiModule.getFiles();
            try {
                ProjectVersion version = getClient().getProjectVersionByName(projectName);
                if (param.getAction().equals("refresh")) {
                    getVfsClient().clearCache(path);
                }
                Folder folder = getClient().getFolderByPath(path, projectName);

                if (folder != null) {
                    if (folder != null) {
                        List<Folder> folders = folder.getChildrenList();
                        for (Folder cfolder : folders) {
                            modules.add(new XUIFile(cfolder, version));
                        }
                        if ((param.getType() == null || param.getType() != 0) && (param.getDeep() == null || !param.getDeep().equals("0"))) {
                            List<FileInfo> infos = folder.getFileList();
                            Map<String, String> nameMap = new HashMap<String, String>();
                            for (FileInfo fileInfo : infos) {

                                if (param.getPattern() != null && !param.getPattern().equals("")) {
                                    Pattern p = Pattern.compile(param.getPattern());
                                    Matcher matcher = p.matcher(fileInfo.getName());
                                    modules.add(new XUIFile(fileInfo, version));
                                } else {
                                    modules.add(new XUIFile(fileInfo, version));
                                }
                            }
                        }

                    }
                }
                result.setData(xuiModule);
            } catch (JDSException e) {
                result = new ErrorResultModel();
                ((ErrorResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
                ((ErrorResultModel) result).setErrdes(e.getMessage());

            }
        }

        return result;
    }

//    @MethodChinaName(cname = "下载文件")
//    @RequestMapping(value = {"get"}, method = {RequestMethod.GET})
//    @ResponseBody
//    public void get(String path, HttpServletResponse response) {
//        // 打开本地文件流
//        InputStream stream = null;
//        try {
//            FileInfo file = getVfsClient().getFileByPath(path);
//            stream = file.getCurrentVersonInputStream();
//            response.setContentType("multipart/form-data");
//            response.setHeader("Content-Disposition", "attachment;fileName=" + file.getName());
//            // 用于记录以完成的下载的数据量，单位是byte
//            long downloadedLength = 0l;
//            // 激活下载操作
//            OutputStream os = response.getOutputStream();
//            // 循环写入输出流
//            byte[] b = new byte[2048];
//            int length;
//            while ((length = stream.read(b)) > 0) {
//                os.write(b, 0, length);
//                downloadedLength += b.length;
//            }
//            os.close();
//            stream.close();
//
//        } catch (IOException e) {
//            e.printStackTrace();
//        } catch (JDSException e) {
//            e.printStackTrace();
//        }
//
//    }

    @MethodChinaName(cname = "保存文件内容")
    @RequestMapping(value = {"saveContent"}, method = {RequestMethod.POST})
    public @ResponseBody
    ResultModel<XUIModule> saveContent(@PathVariable String projectName, String className, String content, String jscontent, String path, EUFileType fileType) {
        ResultModel<XUIModule> result = new ResultModel<XUIModule>();
        XUIModule xuiModule = new XUIModule();

        try {
            ProjectVersion version = getClient().getProjectVersionByName(projectName);
            if (path != null && path.endsWith(".cls")) {
                fileType = EUFileType.EUClass;
            }
            switch (fileType) {
                case EUClass:
                    if (path.endsWith(".js") && jscontent != null) {
                        this.getClient().saveFile(new StringBuffer(jscontent), path, projectName);
                    }
                    ModuleComponent moduleComponent = JSONObject.parseObject(content, ModuleComponent.class);
                    EUModule euModule = version.createModule(path);
                    euModule.setComponent(moduleComponent);
                    this.getClient().saveModule(euModule);
                    break;
                case EUFile:
                    this.getClient().saveFile(new StringBuffer(jscontent), path, projectName);
                    break;
            }
            result.setData(xuiModule);
        } catch (Exception e) {
            e.printStackTrace();
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
            ((ErrorResultModel) result).setErrdes(e.getMessage());

        }


        return result;
    }

    @MethodChinaName(cname = "删除文件版本")
    @RequestMapping(value = {"delFileVersion"}, method = {RequestMethod.POST})
    public @ResponseBody
    ResultModel<Boolean> delFileVersion(String paths, @PathVariable String projectName) {
        ResultModel<Boolean> result = new ResultModel<Boolean>();
        String[] versionIdArr = StringUtility.split(paths, ";");
        for (String versionId : versionIdArr) {
            try {
                getVfsClient().deleteFileVersion(versionId);
            } catch (JDSException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    @MethodChinaName(cname = "获取所有版本")
    @RequestMapping(value = {"getAllFileVersion"}, method = {RequestMethod.POST})
    public @ResponseBody
    ListResultModel<List<XUIFileVersion>> getAllFileVersion(String path, @PathVariable String projectName) {
        ListResultModel<List<XUIFileVersion>> result = new ListResultModel<List<XUIFileVersion>>();
        List<XUIFileVersion> allversions = new ArrayList<XUIFileVersion>();
        try {

            FileInfo fileInfo = getClient().getFileByPath(path, projectName);
            List<FileVersion> versions = fileInfo.getVersionList();
            result = PageUtil.getDefaultPageList(versions, XUIFileVersion.class);
        } catch (JDSException e) {
            result = new ErrorListResultModel();
            ((ErrorListResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
            ((ErrorListResultModel) result).setErrdes(e.getMessage());
        }

        return result;
    }


    ESDClient getClient() throws JDSException {

        ESDClient client = ESDFacrory.getESDClient();

        return client;
    }

    public CtVfsService getVfsClient() {

        CtVfsService vfsClient = CtVfsFactory.getCtVfsService();
        return vfsClient;
    }
}
